home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * NSSDC/CDF Parse qualifiers/options/parameters.
- *
- * Version 1.3, 10-Feb-92, ST Systems (STX)
- *
- * Modification history:
- *
- * V1.0 24-Jun-91, J Love Original version (for CDF V2.1).
- * V1.1 28-Jun-91, J Love TRUE/FALSE.
- * V1.2 23-Sep-91, J Love Modified for IBM-PC port (CDF).
- * V1.3 10-Feb-92, J Love Ignore case on UNIX/MS-DOS machines. Added
- * checking for redundant qualifiers. Added
- * wildcard character (*) option in qualifiers
- * (eg. -cdf and -cdfname will both match -cdf*).
- *
- ******************************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
-
- #include "qop.h"
-
- #define NUL 0
-
- /******************************************************************************
- * Local function prototypes.
- ******************************************************************************/
-
- #if defined(vms) | defined(__MSDOS__)
- int strncmpNOCASEwild (char *, char *, size_t);
- #endif
-
- #if defined(unix)
- int strncmpNOCASEwild ();
- #endif
-
- /******************************************************************************
- * Qop.
- ******************************************************************************/
-
- QOP *Qop (argc, argv, validQuals, optRequired)
- int argc;
- char *argv[];
- char *validQuals[];
- int optRequired[];
- {
- QOP *qop;
- int Nparms = 0;
- int matchQual;
- int i, j;
- char *parms[QOP_MAX_PARMs];
- int qualEntered[QOP_MAX_QUALs];
- char *qualOpt[QOP_MAX_QUALs];
- int strCount = 0;
- char *strOffset;
-
- #if defined(vms)
- int Nquals = 0;
- char *argvTEMP[QOP_MAX_ARGVs];
- char *quals[QOP_MAX_QUALs];
- char *opts[QOP_MAX_QUALs];
- enum modes { UNKNOWN, FIND_QUAL, FIND_QUAL_END, FIND_PARM_END, FIND_OPT,
- FIND_OPT_END } mode;
- #endif
-
- #if defined(vms)
- /*****************************************************************************
- * Determine parameters and qualifiers/options - VMS.
- *****************************************************************************/
-
- for (i = 1; i < argc; i++) {
- argvTEMP[i] = (char *) malloc (strlen(argv[i]) + 1);
- if (argvTEMP[i] == NULL) return NULL; /* CLEAN UP! */
- strcpy (argvTEMP[i], argv[i]);
-
- mode = UNKNOWN;
-
- for (j = 0; argvTEMP[i][j] != NUL; j++)
- switch (mode) {
- case UNKNOWN:
- if (argvTEMP[i][j] == '/')
- mode = FIND_QUAL;
- else {
- Nparms++;
- if (Nparms <= QOP_MAX_PARMs) {
- parms[Nparms-1] = &argvTEMP[i][j];
- }
- else {
- printf ("Too many parameters.\n");
- return NULL;
- }
- mode = FIND_PARM_END;
- }
- break;
- case FIND_QUAL:
- Nquals++;
- if (Nquals <= QOP_MAX_QUALs) {
- quals[Nquals-1] = &argvTEMP[i][j];
- }
- else {
- printf ("Too many qualifiers.\n");
- return NULL;
- }
- mode = FIND_QUAL_END;
- break;
- case FIND_QUAL_END:
- switch (argvTEMP[i][j]) {
- case '/':
- argvTEMP[i][j] = NUL;
- opts[Nquals-1] = NULL;
- mode = FIND_QUAL;
- break;
- case '=':
- argvTEMP[i][j] = NUL;
- mode = FIND_OPT;
- break;
- }
- break;
- case FIND_PARM_END:
- if (argvTEMP[i][j] == '/')
- if (argvTEMP[i][j+1] == '/')
- memmove (&argvTEMP[i][j], &argvTEMP[i][j+1],
- strlen(&argvTEMP[i][j+1]) + 1);
- else {
- argvTEMP[i][j] = NUL;
- mode = FIND_QUAL;
- }
- break;
- case FIND_OPT:
- if (argvTEMP[i][j] == '/')
- if (argvTEMP[i][j+1] == '/') {
- opts[Nquals-1] = &argvTEMP[i][j+1];
- j++;
- mode = FIND_OPT_END;
- }
- else {
- argvTEMP[i][j] = NUL;
- opts[Nquals-1] = &argvTEMP[i][j];
- mode = FIND_QUAL;
- }
- else {
- opts[Nquals-1] = &argvTEMP[i][j];
- mode = FIND_OPT_END;
- }
- break;
- case FIND_OPT_END:
- if (argvTEMP[i][j] == '/')
- if (argvTEMP[i][j+1] == '/')
- memmove (&argvTEMP[i][j], &argvTEMP[i][j+1],
- strlen(&argvTEMP[i][j+1]) + 1);
- else {
- argvTEMP[i][j] = NUL;
- mode = FIND_QUAL;
- }
- break;
- }
-
- switch (mode) {
- case UNKNOWN:
- case FIND_QUAL:
- break;
- case FIND_QUAL_END:
- /* already NUL-terminated */
- opts[Nquals-1] = NULL;
- break;
- case FIND_PARM_END:
- /* already NUL-terminated */
- break;
- case FIND_OPT:
- opts[Nquals - 1] = &argvTEMP[i][j]; /* NUL-string */
- break;
- case FIND_OPT_END:
- /* already NUL-terminated */
- break;
- }
- }
-
- /*****************************************************************************
- * Determine which qualifiers/options were entered - VMS.
- *****************************************************************************/
-
- for (i = 0; validQuals[i] != NULL; i++) {
- if (i < QOP_MAX_QUALs) {
- qualEntered[i] = FALSE;
- qualOpt[i] = NULL;
- }
- else {
- printf ("Too many valid qualifiers.\n");
- return NULL;
- }
- }
-
- for (i = 0; i < Nquals; i++) {
- matchQual = -1;
- for (j = 0; validQuals[j] != NULL; j++)
- if (strncmpNOCASEwild(quals[i], validQuals[j], strlen(quals[i])) == 0)
- if (matchQual != -1) {
- printf ("Ambiguous qualifier (/%s).\n", quals[i]);
- return NULL;
- }
- else {
- matchQual = j;
- }
- if (matchQual != -1)
- if (optRequired[matchQual] && opts[i] == NULL) {
- printf ("Option missing for qualifier /%s.\n", validQuals[matchQual]);
- return NULL;
- }
- else {
- if (qualEntered[matchQual]) {
- printf ("Redundant qualifier (/%s).\n", validQuals[matchQual]);
- return NULL;
- }
- else {
- qualEntered[matchQual] = TRUE;
- qualOpt[matchQual] = opts[i];
- }
- }
- else {
- printf ("Unknown qualifier (/%s).\n", quals[i]);
- return NULL;
- }
- }
- #endif
-
- #if defined(unix) | defined(__MSDOS__)
- /*****************************************************************************
- * Determine which qualifiers/options were entered - UNIX/MS-DOS.
- *****************************************************************************/
-
- for (i = 0; validQuals[i] != NULL; i++) {
- if (i < QOP_MAX_QUALs) {
- qualEntered[i] = FALSE;
- qualOpt[i] = NULL;
- }
- else {
- printf ("Too many valid qualifiers.\n");
- return NULL;
- }
- }
-
- for (i = 1; i < argc; i++)
- if (argv[i][0] == '-') {
- matchQual = -1;
-
- for (j = 0; validQuals[j] != NULL; j++)
- if (strncmpNOCASEwild(&argv[i][1],
- validQuals[j], strlen(&argv[i][1])) == 0)
- if (matchQual != -1) {
- printf ("Ambiguous qualifier (-%s).\n", &argv[i][1]);
- return NULL;
- }
- else
- matchQual = j;
-
- if (matchQual != -1) {
- if (qualEntered[matchQual]) {
- printf ("Redundant qualifier (-%s).\n", validQuals[matchQual]);
- return NULL;
- }
- else {
- qualEntered[matchQual] = TRUE;
- }
-
- if (optRequired[matchQual])
- if (i+1 < argc) {
- qualOpt[matchQual] = argv[i+1];
- i++;
- }
- else {
- printf ("Option missing for qualifier -%s.\n",
- validQuals[matchQual]);
- return NULL;
- }
- }
- else {
- printf ("Unknown qualifier (-%s).\n", &argv[i][1]);
- return NULL;
- }
- }
- else {
- Nparms++;
- if (Nparms <= QOP_MAX_PARMs) {
- parms[Nparms-1] = argv[i];
- }
- else {
- printf ("Too many parameters.\n");
- return NULL;
- }
- }
- #endif
-
- /******************************************************************************
- * Build QOP structure.
- ******************************************************************************/
-
- for (i = 0; i < Nparms; i++) strCount += strlen(parms[i]) + 1;
-
- for (i = 0; validQuals[i] != NULL; i++)
- if (qualEntered[i])
- if (qualOpt[i] != NULL) strCount += strlen(qualOpt[i]) + 1;
-
- qop = (QOP *) malloc (sizeof(QOP) + strCount);
- if (qop == NULL) return NULL;
-
- strOffset = (char *) qop + sizeof(QOP);
-
- qop->Nparms = Nparms;
-
- for (i = 0; i < Nparms; i++) {
- qop->parms[i] = strOffset;
- strOffset += strlen(parms[i]) + 1;
- strcpy (qop->parms[i], parms[i]);
- }
-
- for (i = 0; validQuals[i] != NULL; i++) {
- qop->qualEntered[i] = qualEntered[i];
- if (qualEntered[i])
- if (qualOpt[i] != NULL) {
- qop->qualOpt[i] = strOffset;
- strOffset += strlen(qualOpt[i]) + 1;
- strcpy (qop->qualOpt[i], qualOpt[i]);
- }
- else
- qop->qualOpt[i] = NULL;
- }
-
- /******************************************************************************
- * Free memory used.
- ******************************************************************************/
-
- #if defined(vms)
- for (i = 1; i < argc; i++) free (argvTEMP[i]);
- #endif
-
- /*****************************************************************************/
-
- return qop;
- }
-
- /******************************************************************************
- * strncmpNOCASEwild.
- ******************************************************************************/
-
- static int strncmpNOCASEwild (s1, s2, len)
- char *s1;
- char *s2;
- size_t len;
- {
- int i;
-
- for (i = 0; i < len; i++)
- switch (s1[i]) {
- case NUL:
- if (s2[i] == '*')
- return 0;
- else
- return -s2[i];
- case '*':
- return 0;
- default:
- switch (s2[i]) {
- case NUL:
- return s1[i];
- case '*':
- return 0;
- default:
- if ((islower(s1[i]) ? toupper(s1[i]) : s1[i]) !=
- (islower(s2[i]) ? toupper(s2[i]) : s2[i])) return s1[i] - s2[i];
- }
- }
-
- return 0;
- }
-